/**
 * 网络请求工具类
 */
import { BASE_URL, TIMEOUT, HEADERS, STATUS_CODE } from './config.js';

/**
 * 请求拦截器
 * @param {Object} options - 请求配置
 * @returns {Object} - 处理后的请求配置
 */
const requestInterceptor = (options) => {
  // 获取token（如果有的话）
  const token = uni.getStorageSync('token');
  if (token) {
    options.header = {
      ...options.header,
      'Authorization': `Bearer ${token}`
    };
  }
  return options;
};

/**
 * 响应拦截器
 * @param {Object} response - 响应数据
 * @returns {Object|Promise} - 处理后的响应数据或错误
 */
const responseInterceptor = (response) => {
  // 请求成功
  if (response.statusCode === STATUS_CODE.SUCCESS) {
    return response.data;
  }
  
  // 处理特定状态码
  switch (response.statusCode) {
    case STATUS_CODE.UNAUTHORIZED:
      // 未授权，清除token并跳转到登录页
      uni.removeStorageSync('token');
      uni.showToast({
        title: '登录已过期，请重新登录',
        icon: 'none'
      });
      setTimeout(() => {
        uni.navigateTo({
          url: '/pages/login/index'
        });
      }, 1500);
      return Promise.reject(new Error('未授权'));
      
    case STATUS_CODE.FORBIDDEN:
      uni.showToast({
        title: '没有权限访问',
        icon: 'none'
      });
      return Promise.reject(new Error('禁止访问'));
      
    case STATUS_CODE.NOT_FOUND:
      return Promise.reject(new Error('资源不存在'));
      
    case STATUS_CODE.SERVER_ERROR:
      uni.showToast({
        title: '服务器错误，请稍后再试',
        icon: 'none'
      });
      return Promise.reject(new Error('服务器错误'));
      
    default:
      return Promise.reject(new Error(response.data.message || '未知错误'));
  }
};

/**
 * 错误处理函数
 * @param {Error} error - 错误对象
 * @returns {Promise} - 被拒绝的Promise
 */
const errorHandler = (error) => {
  // 网络错误
  if (error.errMsg && error.errMsg.includes('request:fail')) {
    uni.showToast({
      title: '网络连接失败，请检查网络设置',
      icon: 'none'
    });
  }
  
  return Promise.reject(error);
};

/**
 * 发送HTTP请求
 * @param {Object} options - 请求配置
 * @returns {Promise} - 请求Promise
 */
const request = (options) => {
  // 合并默认配置
  const requestOptions = {
    url: `${BASE_URL}${options.url}`,
    timeout: TIMEOUT,
    header: { ...HEADERS, ...options.header },
    ...options
  };
  
  // 应用请求拦截器
  const processedOptions = requestInterceptor(requestOptions);
  
  // 发送请求并处理响应
  return new Promise((resolve, reject) => {
    uni.request({
      ...processedOptions,
      success: (res) => {
        try {
          const result = responseInterceptor(res);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      },
      fail: (err) => {
        errorHandler(err);
        reject(err);
      }
    });
  });
};

/**
 * GET请求
 * @param {string} url - 请求URL
 * @param {Object} params - 请求参数
 * @param {Object} header - 请求头
 * @returns {Promise} - 请求Promise
 */
const get = (url, params = {}, header = {}) => {
  return request({
    url,
    method: 'GET',
    data: params,
    header
  });
};

/**
 * POST请求
 * @param {string} url - 请求URL
 * @param {Object} data - 请求数据
 * @param {Object} header - 请求头
 * @returns {Promise} - 请求Promise
 */
const post = (url, data = {}, header = {}) => {
  return request({
    url,
    method: 'POST',
    data,
    header
  });
};

/**
 * PUT请求
 * @param {string} url - 请求URL
 * @param {Object} data - 请求数据
 * @param {Object} header - 请求头
 * @returns {Promise} - 请求Promise
 */
const put = (url, data = {}, header = {}) => {
  return request({
    url,
    method: 'PUT',
    data,
    header
  });
};

/**
 * DELETE请求
 * @param {string} url - 请求URL
 * @param {Object} data - 请求数据
 * @param {Object} header - 请求头
 * @returns {Promise} - 请求Promise
 */
const del = (url, data = {}, header = {}) => {
  return request({
    url,
    method: 'DELETE',
    data,
    header
  });
};

/**
 * 上传文件
 * @param {string} url - 上传URL
 * @param {string} filePath - 文件路径
 * @param {string} name - 文件对应的key
 * @param {Object} formData - 附加的表单数据
 * @param {Object} header - 请求头
 * @returns {Promise} - 上传Promise
 */
const upload = (url, filePath, name = 'file', formData = {}, header = {}) => {
  const token = uni.getStorageSync('token');
  const uploadHeader = token ? { ...header, 'Authorization': `Bearer ${token}` } : header;
  
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: `${BASE_URL}${url}`,
      filePath,
      name,
      formData,
      header: { ...HEADERS, ...uploadHeader },
      success: (res) => {
        if (res.statusCode === STATUS_CODE.SUCCESS) {
          // 上传成功，解析响应数据
          let data;
          try {
            data = JSON.parse(res.data);
          } catch (e) {
            data = res.data;
          }
          resolve(data);
        } else {
          // 处理错误
          try {
            const result = responseInterceptor({
              statusCode: res.statusCode,
              data: typeof res.data === 'string' ? JSON.parse(res.data) : res.data
            });
            resolve(result);
          } catch (error) {
            reject(error);
          }
        }
      },
      fail: (err) => {
        errorHandler(err);
        reject(err);
      }
    });
  });
};

export {
  request,
  get,
  post,
  put,
  del,
  upload
};